﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GEAR_Structure.UNI.Acoustic
{
    class UniTr11175
    {
        /// <summary>
        /// Calcola l'indice del potere fonoisolante
        /// </summary>
        public static class R1w
        {
            /// <summary>
            /// Calcola il valore del Parametro M dato dal logaritmo del raporto fra masse perpendicolari
            /// </summary>
            /// <param name="mpi">massa perpendicolare alla principale</param>
            /// <param name="mi">massa principale</param>
            /// <returns>Parametro M</returns>
            private static double Mij(double mpi, double mi)
            {
                //Il valore di mpi(Perpendicolare) e mi sono masse superficiali espressi in kg/m²
                double M;
                M = Math.Log10(mpi / mi);
                return M;
            }

            //definisco il vettore per assegnare i valore predefiniti secondo la norma
            //UNI TR 11175

            /// <summary>
            /// Restituisce il Parametro Kij per le trasmisioni laterali in funzione della tipologia di giunto
            /// </summary>
            /// <param name="tipo">Tipo di giunto secondo tabella della UNI 11175</param>
            /// <param name="mpi">Massa perpendicolare</param>
            /// <param name="mi">massa principale</param>
            /// <param name="Si">Superficie lato Sorgente</param>
            /// <param name="Sj">Superficie Lato Ricevente</param>
            /// <param name="lij">lughezza giunto</param>
            /// <returns></returns>
            public static double parametroKij(int tipo, double mpi, double mi, double Si, double Sj, double lij)
            {
                //IL METTODO RICHIEDE I SEGUENTI DATI 
                //Tipo di giunto presente secondo tabella norma UNI TR 11175 
                //Indicare inoltre le due masse superficiali coinvolte in (kg/m²) mpi e mi
                //Indicare le superfici relative alle pareti considerate Si ed Sj
                //Indicare la lunghezza del giunto relativo alle pareti considerate
                double K = 0, Kij;

                Kij = 10 * Math.Log10(lij * (1 / Si + 1 / Sj));


                //Giunzione rigida a croce (collegamento tra pareti pesanti, ad esempio in laterizi)

                if (tipo == 1)
                {
                    K = (87 / 10) + (171 / 10) * Mij(mpi, mi) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);

                }
                if (tipo == 2)
                {
                    K = (87 / 10) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);
                }
                //Giunzione a T (collegamento tra pareti pesanti, ad esempio in laterizi)
                if (tipo == 3)
                {
                    K = (57 / 10) + (141 / 10) * Mij(mpi, mi) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);
                }

                if (tipo == 4)
                {
                    K = (57 / 10) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);
                }
                //Struttura omogenea e facciata legera
                if (tipo == 5)
                {
                    K = 5 + 10 * Mij(mpi, mi);
                }
                if (tipo == 6)
                {
                    K = 5 + 10 * Math.Abs(Mij(mpi, mi));
                }
                //strutture omogenee con strato desolidarizante
                if (tipo == 7)
                {
                    K = (57 / 10) + (141 / 10) * Mij(mpi, mi) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2) + 12;
                }
                if (tipo == 8)
                {
                    K = (37 / 10) + (141 / 10) * Mij(mpi, mi) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);
                }
                if (tipo == 9)
                {
                    K = (57 / 10) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2) + 6;
                }
                //Struttura omogenea con angolo
                if (tipo == 10)
                {
                    K = 15 * Math.Abs(Mij(mpi, mi)) - 3;
                }
                //struttura omogenea con cambio di spessore
                if (tipo == 11)
                {
                    K = 5 * Math.Pow(Mij(mpi, mi), 2) - 5;
                }
                //Doppia parete leggera e struttura omogenea
                if (tipo == 12)
                {
                    K = 10 + 20 * Mij(mpi, mi);
                }
                if (tipo == 13)
                {
                    K = 3 + (141 / 10) * Mij(mpi, mi) + (57 / 10) * Math.Pow(Mij(mpi, mi), 2);
                }
                if (tipo == 14)
                {
                    K = 10 + 10 * Math.Abs(Mij(mpi, mi));
                }
                //Pareti doppie legere accoppiate
                if (tipo == 15)
                {
                    K = 10 + 20 * Mij(mpi, mi);
                }
                if (tipo == 16)
                {
                    K = 10 + 10 * Math.Abs(Mij(mpi, mi));
                }


                //verifica se K è maggiore del valore minimo previsto
                //e se non lo è lo ridefinisce sulla base del minimo valore

                if (K <= Kij)
                {
                    K = Kij;
                }

                return Convert.ToDouble(Math.Round(K, 2));

            }

            /// <summary>
            /// Calcola le tre componenti di trasmissione laterali per le diverse tipologie di giunto
            /// </summary>
            /// <param name="md">massa superficiale del divisorio [kg/m²]</param>
            /// <param name="ms">massa superficiale del muro lato sorgente [kg/m²]</param>
            /// <param name="mr">massa superficiale del muro lato ricevente [kg/m²]</param>
            /// <param name="lij">lunghezza del giunto considerato espereaa in metri [m]</param>
            /// <param name="Sd">superficie del divisorio [m²]</param>
            /// <param name="Ss">superficie del muro lato sorgente [m²]</param>
            /// <param name="Sr">superficie del muro lato ricevente[m²]</param>
            /// <param name="Ff">trasmissione laterale</param>
            /// <param name="Fd">trasmissione laterale</param>
            /// <param name="Df">trasmissione laterale</param>
            /// <param name="tipo">tipo di giunto e di percorso come da prospetto 3 pagine 13 della UNI TR 11175</param>
            /// <returns>Ff</returns>
            public static double Kij(double md, double ms, double mr, double lij, double Sd, double Ss,
                double Sr, ref double Ff, ref double Fd, ref double Df, int tipo)
            {
                /*
                Kij mettodo per calcolare le tre Kij per ciascuna tipologia di giunto occore
                fornire nel seguente ordine:
                md= massa superficiale del divisorio [kg/m²]
                ms= massa superficiale del muro lato sorgente [kg/m²]
                mr=massa superficiale del muro lato ricevente [kg/m²]
                lij=lunghezza del giunto considerato espereaa in metri [m]
                Sd=superficie del divisorio [m²]
                Ss= superficie del muro lato sorgente [m²]
                Sr=superficie del muro lato ricevente[m²]
                Ff, Fd, Df= sono i contributi dovuti alla trasmissione laterale variano in funzione del tipo di giunto
                è sono impostati inizialmente a zero; nel caso di un divisorio con quattro lati
                avremo che il numero di questi contributi sarà dato dal numero dei lati per tre
                cioè 4lati x 3contributi =12 contributi totali.
                tipo=rapresenta il tipo di giunto e di percorso come da prospetto 3 pagine 13 della UNI TR 11175
               */
                if (tipo == 1)
                {
                    Ff = parametroKij(tipo, md, ms, Ss, Sr, lij);
                    Fd = parametroKij((tipo + 1), ms, md, Ss, Sd, lij);
                    Df = Fd;
                }
                if (tipo == 2)
                {
                    Ff = parametroKij((tipo - 1), md, ms, Ss, Sr, lij);
                    Fd = parametroKij(tipo, ms, md, Ss, Sd, lij);
                    Df = Fd;
                }
                if (tipo == 3)
                {
                    Ff = parametroKij(tipo, md, ms, Ss, Sr, lij);
                    Fd = parametroKij(tipo, ms, md, Ss, Sd, lij);
                    Df = Fd;

                }
                if (tipo == 4)
                {
                    Ff = parametroKij((tipo - 1), md, ms, Ss, Sr, lij);
                    Fd = parametroKij(tipo, ms, md, Ss, Sd, lij);
                    Df = Fd;
                }

                return Ff;
            }

            /// <summary>
            /// Calcola l'indice del potere fonoisolante secondo le diverse formule della normativa
            /// </summary>
            /// <param name="_frontal_mass">massa superficiale dell'elemento considerato in [kg/m²]</param>
            /// <param name="formula">Numero associato alla formula da usare</param>
            /// <returns>Rw indice del potere fonoisolante</returns>
            public static double Rw(double _frontal_mass, int _formula_sound_index)
            {
                /*
                 *Il metodo calcola l'indice del potere fonoisolante dei diversi elementi che
                 *compongono il sistema i dati in ingresso che servono sono i seguenti:
                 *m= massa superficiale dell'elemento considerato in [kg/m²]
                 *formula = tipo di formula da utilizzare per il calcolo fra quelle messe
                 *a disposizione dalla norma UNI. le formule sono cosi inserite:
                 *Relazioni proposte da rapporto tecnico UNI TR 11175
                 *Formula Laboratori italiani
                 *0=20log(m)-2
                 *Formula CEN
                 *2=37,5log(m)-44 
                */
                double Rw;

                switch (_formula_sound_index)
                {
                    case 1:
                        Rw = 20 * Math.Log10(_frontal_mass);
                        break;
                    case 2:
                        Rw = 37.5 * Math.Log10(_frontal_mass) - 42;
                        break;
                    case 3:
                        Rw = 37.5 * Math.Log10(_frontal_mass) - 44;
                        break;
                    case 4:

                        Rw = 20 * Math.Log10(_frontal_mass) - 2;
                        break;
                    default:
                        Rw = 0;
                        break;
                }

                return Rw;
            }
            /// <summary>
            /// Calcola l'indice del potere fonoisolante secondo le diverse formule della normativa
            /// </summary>
            /// <param name="str">stratigrafia del componente edilizio</param>
            /// <returns>Rw</returns>
            public static double Rw(Stratigraphy str)
            {
                /*
                 *Il metodo calcola l'indice del potere fonoisolante dei diversi elementi che
                 *compongono il sistema i dati in ingresso che servono sono i seguenti:
                 *m= massa superficiale dell'elemento considerato in [kg/m²]
                 *formula = tipo di formula da utilizzare per il calcolo fra quelle messe
                 *a disposizione dalla norma UNI. le formule sono cosi inserite:
                 *Relazioni proposte da rapporto tecnico UNI TR 11175
                 *Formula Laboratori italiani
                 *0=20log(m)-2
                 *Formula CEN
                 *2=37,5log(m)-44 
                */
                double Rw;
                double _frontal_mass = str.FrontalMass;



                switch (Convert.ToInt32(str.Formula_sound_index))
                {
                    case 1:
                        Rw = 20 * Math.Log10(_frontal_mass);
                        break;
                    case 2:
                        Rw = 37.5 * Math.Log10(_frontal_mass) - 42;
                        break;
                    case 3:
                        Rw = 37.5 * Math.Log10(_frontal_mass) - 44;
                        break;
                    case 4:

                        Rw = 20 * Math.Log10(_frontal_mass) - 2;
                        break;
                    default:
                        Rw = 0;
                        break;
                }

                return Rw;
            }

            /// <summary>
            /// Calcola Rijw per i diversi percorsi
            /// </summary>
            /// <param name="Ri_w">Rw parete i</param>
            /// <param name="Rj_w">Rw parete j</param>
            /// <param name="DRij_w">contributo</param>
            /// <param name="Kij">Percorso i-j</param>
            /// <param name="Sd">Superficie del divisorio</param>
            /// <param name="lij">lunghezza giunto considerato</param>
            /// <returns>Rijw</returns>
            private static double Rij_w(double Ri_w, double Rj_w, double DRij_w,
                double Kij, double Sd, double lij)
            {
                /*
                 *Questo metodo serve per calcolare il contributo dato dai vari percorsi
                 *richiede in ingresso i poteri fonoisolanti delle due pareti interessate
                 *dal percorso ij, l'ingremento DRij dovuto alla presenza di strati addizonali
                 *la superficie Sd della partizione e la lunghezza del giunto interessato.
                 *Si richiede inoltre il parametro Kij.
               */

                double Rij_w = 0;

                Rij_w = ((Ri_w + Rj_w) / 2) + DRij_w + Kij + (10 * Math.Log10(Sd / lij));

                return Rij_w;
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="n"></param>
            /// <param name="tipo"></param>
            /// <param name="str"></param>
            /// <param name="lij"></param>
            /// <param name="formulaRw"></param>
            /// <returns></returns>
            public static double R1W(int n, int[] tipo, double[,] str, double[] lij,
                int formulaRw)
            {
                /*
                 * definisco la matrice dei dati la riga zero contiene i dati
                 * dell'elemento divisorio oggetto del calcolo.
                 * Il primo parametro del metodo definisce il numero dei lati del
                 * //divisorio questo deve essere >=3
                 * Il secondo parametro "vettore" indica il tipo dei giunti presenti
                 * //per ciscun lato del divisorio
                 * IL terzo parametro (matrice strutture) "str" indica la superficie,
                 * //la massa "mi", la massa agiunta "mia" e la tipologia (0, 1 o 2)
                 * //di ciscun elemento dove: 0=massa monolitica mia=0, 1=mia esterna, 2=mia interna
                 * Il quarto parametro (vettore) indica la lunghezza dei giunti presenti
                 * Il Quinto Parametro la formula che intendo usare per calcolare Rw
               */

                double R1w = 0;
                int i;

                //definisco ora la struttura dati questa avrà tante righe quanti sono
                //gli elementi considerati pari a M=[(n*2)+1] e un numero di colonne pari alle caratteristiche
                //necessarie per eseguire i calcoli che devono essere inserite nella
                //matrice ne seguente ordine
                //1= massa elemento [kg/m²]
                //2=Superficie elemento [m²]
                //3=lunghezza giunto

                //inizializzo le variabili
                double Ff = 0, Fd = 0, Df = 0;
                int M = (n * 2) + 1;
                int righe = M;

                double[] DatiKij = new double[(n * 3 + 1)];
                double[,] DatiRw = new double[M, 2];
                double[,] DatiRw_ij = new double[((n * 3) + 1), 8];

                for (i = 0; i < n; i++)
                {
                    //Assegno i valori Kij al vettore per ciascun percorso (3 per lato)
                    // 0 //
                    ///////
                    //Ff//
                    //////
                    //Fd//
                    //////
                    //Df//
                    //////

                    Kij(str[0, 1], str[i + 1, 1], str[(i + 1 + n), 1], lij[i], str[0, 0], str[i + 1, 0], str[(i + 1 + n), 0], ref Ff, ref Fd, ref Df, tipo[i]);
                    DatiKij[3 * i + 1] = Ff;
                    DatiKij[3 * i + 2] = Fd;
                    DatiKij[3 * i + 3] = Df;
                }



                for (M = 0; M < righe; M++)
                {
                    DatiRw[M, 0] = Rw(str[M, 1], formulaRw);
                    DatiRw[M, 1] = 0;

                }

                {
                    DatiRw_ij[0, 7] = DatiRw[0, 0];
                }



                for (i = 1; i <= n; i++)
                {
                    //Assegno e calcolo i dati per i percorsi Ff, Fd, Df
                    //uttilizzo il seguente schema
                    /////// 0 // 1 ////// 2 //// 3 ////// 4 ////// 5 /// 6 /// 7 /// 
                    ////////////////////////////////////////////////////////////////
                    //000//Rwi////Rwj////DRwi//DRwj/////DRwij/////Kij//10log//Rwij//
                    ////////////////////////////////////////////////////////////////
                    //001//Rw1//Rw_n+1//Drw1///DRw_n+1//DRw1_n+1//   //     //    //
                    ////////////////////////////////////////////////////////////////

                    //colonna0
                    DatiRw_ij[i, 0] = DatiRw[i, 0];//F
                    DatiRw_ij[(n + i), 0] = DatiRw[i, 0];//F
                    DatiRw_ij[(2 * n + i), 0] = DatiRw[0, 0];//D
                    //colonna1
                    DatiRw_ij[i, 1] = DatiRw[n + i, 0]; //f
                    DatiRw_ij[(n + i), 1] = DatiRw[0, 0];//d
                    DatiRw_ij[(2 * n + i), 1] = DatiRw[n + i, 0];//f
                    //colonna2
                    DatiRw_ij[i, 2] = DatiRw[i, 1];//F
                    DatiRw_ij[(n + i), 2] = DatiRw[i, 1];//F
                    DatiRw_ij[(2 * n + i), 2] = DatiRw[0, 1];//D
                    //colonna3
                    DatiRw_ij[i, 3] = DatiRw[n + i, 1]; //f
                    DatiRw_ij[(n + i), 3] = DatiRw[0, 1];//d
                    DatiRw_ij[(2 * n + i), 3] = DatiRw[n + i, 1];//f
                    //colonna4
                    DatiRw_ij[i, 4] = 2;
                    //colonna5
                    DatiRw_ij[i, 5] = DatiKij[3 * (i - 1) + 1];
                    DatiRw_ij[n + i, 5] = DatiKij[3 * (i - 1) + 2];
                    DatiRw_ij[2 * n + i, 5] = DatiKij[3 * (i - 1) + 3];
                    //collonna6
                    DatiRw_ij[i, 6] = 4;
                    //colonna7
                    DatiRw_ij[i, 7] = Rij_w(DatiRw_ij[i, 0], DatiRw_ij[i, 1], DatiRw_ij[i, 4],
                        DatiRw_ij[i, 5], str[0, 0], lij[i - 1]);
                    DatiRw_ij[n + i, 7] = Rij_w(DatiRw_ij[n + i, 0], DatiRw_ij[n + i, 1], DatiRw_ij[n + i, 4],
                        DatiRw_ij[n + i, 5], str[0, 0], lij[i - 1]);
                    DatiRw_ij[2 * n + i, 7] = Rij_w(DatiRw_ij[2 * n + i, 0], DatiRw_ij[2 * n + i, 1], DatiRw_ij[2 * n + i, 4],
                        DatiRw_ij[2 * n + i, 5], str[0, 0], lij[i - 1]);

                }

                for (i = 0; i < ((n * 3) + 1); i++)
                {
                    R1w += Math.Pow(10, (-DatiRw_ij[i, 7] / 10));
                }

                R1w = -10 * Math.Log10(R1w);






                return R1w;
            }
            /// <summary>
            /// Calcola R'w dell'elemento considerato
            /// </summary>
            /// <param name="tipo">Vettore contenente la tipologia dei giunti presente</param>
            ///<param name="Rw"> vettore contenente gli indici del potere fonoisolante dei diversi componenti a partire dal divisorio</param>
            /// <param name="str">matrice contenente le carateristiche delle strutture nel seguente ordine[superficie,Massa, Massa Agiunta,tipologia]per ciuascuna struttura ad iniziare dal divisorio</param>
            /// <param name="lij">il vettore lij riporta le lunghezze dei vari giunti presenti nello stesso ordine del vettore tipo</param>
            /// <returns></returns>
            public static double R1W(int[] tipo, double[] Rw, double[,] str, double[] lij)
            {
                /*
                 * definisco la matrice dei dati la riga zero contiene i dati
                 * dell'elemento divisorio oggetto del calcolo.
                 * Il primo parametro "vettore" indica il tipo dei giunti presenti
                 * //per ciscun lato del divisorio
                 * IL terzo parametro (matrice strutture) "str" indica la superficie,
                 * //la massa "mi", la massa agiunta "mia" e la tipologia (0, 1 o 2)
                 * //di ciscun elemento dove: 0=massa monolitica mia=0, 1=mia esterna, 2=mia interna
                 * Il quarto parametro (vettore) indica la lunghezza dei giunti presenti
             
               */

                double R1w = 0;
                int i;
                int n = tipo.GetLength(0);

                //definisco ora la struttura dati questa avrà tante righe quanti sono
                //gli elementi considerati pari a M=[(n*2)+1] e un numero di colonne pari alle caratteristiche
                //necessarie per eseguire i calcoli che devono essere inserite nella
                //matrice ne seguente ordine
                //1= massa elemento [kg/m²]
                //2=Superficie elemento [m²]
                //3=lunghezza giunto

                //inizializzo le variabili
                double Ff = 0, Fd = 0, Df = 0;
                int M = (n * 2) + 1;
                int righe = M;

                double[] DatiKij = new double[(n * 3 + 1)];
                double[,] DatiRw = new double[M, 2];
                double[,] DatiRw_ij = new double[((n * 3) + 1), 8];

                for (i = 0; i < n; i++)
                {
                    //Assegno i valori Kij al vettore per ciascun percorso (3 per lato)
                    // 0 //
                    ///////
                    //Ff//
                    //////
                    //Fd//
                    //////
                    //Df//
                    //////

                    Kij(str[0, 1], str[i + 1, 1], str[(i + 1 + n), 1], lij[i], str[0, 0], str[i + 1, 0], str[(i + 1 + n), 0], ref Ff, ref Fd, ref Df, tipo[i]);
                    DatiKij[3 * i + 1] = Ff;
                    DatiKij[3 * i + 2] = Fd;
                    DatiKij[3 * i + 3] = Df;
                }



                for (M = 0; M < righe; M++)
                {
                    DatiRw[M, 0] = Rw[M];
                    DatiRw[M, 1] = 0;

                }

                {
                    DatiRw_ij[0, 7] = DatiRw[0, 0];
                }



                for (i = 1; i <= n; i++)
                {
                    //Assegno e calcolo i dati per i percorsi Ff, Fd, Df
                    //uttilizzo il seguente schema
                    /////// 0 // 1 ////// 2 //// 3 ////// 4 ////// 5 /// 6 /// 7 /// 
                    ////////////////////////////////////////////////////////////////
                    //000//Rwi////Rwj////DRwi//DRwj/////DRwij/////Kij//10log//Rwij//
                    ////////////////////////////////////////////////////////////////
                    //001//Rw1//Rw_n+1//Drw1///DRw_n+1//DRw1_n+1//   //     //    //
                    ////////////////////////////////////////////////////////////////

                    //colonna0
                    DatiRw_ij[i, 0] = DatiRw[i, 0];//F
                    DatiRw_ij[(n + i), 0] = DatiRw[i, 0];//F
                    DatiRw_ij[(2 * n + i), 0] = DatiRw[0, 0];//D
                    //colonna1
                    DatiRw_ij[i, 1] = DatiRw[n + i, 0]; //f
                    DatiRw_ij[(n + i), 1] = DatiRw[0, 0];//d
                    DatiRw_ij[(2 * n + i), 1] = DatiRw[n + i, 0];//f
                    //colonna2
                    DatiRw_ij[i, 2] = DatiRw[i, 1];//F
                    DatiRw_ij[(n + i), 2] = DatiRw[i, 1];//F
                    DatiRw_ij[(2 * n + i), 2] = DatiRw[0, 1];//D
                    //colonna3
                    DatiRw_ij[i, 3] = DatiRw[n + i, 1]; //f
                    DatiRw_ij[(n + i), 3] = DatiRw[0, 1];//d
                    DatiRw_ij[(2 * n + i), 3] = DatiRw[n + i, 1];//f
                    //colonna4
                    DatiRw_ij[i, 4] = 2;
                    //colonna5
                    DatiRw_ij[i, 5] = DatiKij[3 * (i - 1) + 1];
                    DatiRw_ij[n + i, 5] = DatiKij[3 * (i - 1) + 2];
                    DatiRw_ij[2 * n + i, 5] = DatiKij[3 * (i - 1) + 3];
                    //collonna6
                    DatiRw_ij[i, 6] = 4;
                    //colonna7
                    DatiRw_ij[i, 7] = Rij_w(DatiRw_ij[i, 0], DatiRw_ij[i, 1], DatiRw_ij[i, 4],
                        DatiRw_ij[i, 5], str[0, 0], lij[i - 1]);
                    DatiRw_ij[n + i, 7] = Rij_w(DatiRw_ij[n + i, 0], DatiRw_ij[n + i, 1], DatiRw_ij[n + i, 4],
                        DatiRw_ij[n + i, 5], str[0, 0], lij[i - 1]);
                    DatiRw_ij[2 * n + i, 7] = Rij_w(DatiRw_ij[2 * n + i, 0], DatiRw_ij[2 * n + i, 1], DatiRw_ij[2 * n + i, 4],
                        DatiRw_ij[2 * n + i, 5], str[0, 0], lij[i - 1]);

                }

                for (i = 0; i < ((n * 3) + 1); i++)
                {
                    R1w += Math.Pow(10, (-DatiRw_ij[i, 7] / 10));
                }

                R1w = -10 * Math.Log10(R1w);






                return R1w;
            }

        }
        /// <summary>
        /// Calcola l'indice di calpestio
        /// </summary>
        public static class L1_nw
        {
            /// <summary>
            /// Calcola l'indice del livello di rumore di calpestio L'nw
            /// </summary>
            /// <param name="Lnweq">Livello di rumore di calpestio equivalente</param>
            /// <param name="DLw">Indice di valutazione relativo</param>
            /// <param name="K">Correzione da aportare dipende da una tabella</param>
            /// <returns>Indice del livello di rumore da calpestio</returns>
            public static double L1nw(double Lnweq, double DLw, double K)
            {
                double L1nw = 0;

                L1nw = Lnweq - DLw + K;

                return L1nw;

            }
            /// <summary>
            /// Calcola il livello di calpestio equivalente
            /// </summary>
            /// <param name="formula">tipologia di formula da usare può essere 1 o 2 altrimenti sarà restituito 0</param>
            /// <param name="m1">é la massa superficiale dei solai al di sotto del massetto gallegiante in [kg/m²]</param>
            /// <returns></returns>
            public static double Lnweq(int formula, double m1)
            {

                double Lnweq = 0, m1o = 1;

                switch (formula)
                {
                    case 1:
                        Lnweq = 164 - 35 * Math.Log10(m1 / m1o);
                        break;
                    case 2:
                        Lnweq = 160 - 30 * Math.Log10(m1 / m1o);
                        break;
                    default:
                        Lnweq = 0;
                        break;

                }

                return Lnweq;

            }

            /// <summary>
            /// Indice di valutazone relativo alla riduzione dei rumori
            /// </summary>
            /// <param name="TipoMassetto">Tipologia massetto 1=per massetti gallegianti in cls 2=per massetti gallegianti a secco</param>
            /// <param name="s1">rigidità dinamica dello strato resiliente in[MN/m³]</param>
            /// <param name="m1s">massa superficiale del massetto gallegiante sopra lo strato resiliente in [kg/m²]</param>
            /// <returns>DLw</returns>
            public static double DLw(int TipoMassetto, double s1, double m1s)
            {
                double DLw = 0, f = 500, fo = 0;

                //calcolo la frequenza di risonanza del sistema
                fo = 160 * Math.Sqrt(s1 / m1s);

                switch (TipoMassetto)
                {
                    case 1:
                        DLw = 30 * Math.Log10(f / fo) + 3;
                        break;
                    case 2:
                        DLw = 40 * Math.Log10(f / fo) - 3;
                        break;
                    default:
                        DLw = 0;
                        break;
                }



                return DLw;
            }
            /// <summary>
            /// restituisce il parametro k
            /// </summary>
            /// <param name="ms">massa superficiale del solaio portante in [kg/m²] al disotto del tapetino resiliente</param>
            /// <param name="mmp">massa superficiale media delle pareti laterali in [kg/m²]</param>
            /// <returns>k</returns>
            public static double K(double ms, double mmp)
            {
                double[][] Ktab = new double[14][]   {
           new double [10] {0,100,150,200,250,300,350,400,450,500},
           new double [10]{100,1,0,0,0,0,0,0,0,0},
           new double [10]{150,1,1,0,0,0,0,0,0,0},
           new double [10]{200,2,1,1,0,0,0,0,0,0},
           new double [10]{250,2,1,1,1,0,0,0,0,0},
           new double [10]{300,3,2,1,1,1,0,0,0,0},
           new double [10]{350,3,2,1,1,1,1,0,0,0},
           new double [10]{400,4,2,2,1,1,1,1,0,0},
           new double [10]{450,4,3,2,2,1,1,1,1,1},
           new double [10]{500,4,3,2,2,1,1,1,1,1},
           new double [10]{600,5,4,3,2,2,1,1,1,1},
           new double [10]{700,5,4,3,3,2,2,1,1,1},
           new double [10]{800,6,4,4,3,2,2,2,1,1},
           new double [10]{900,6,5,4,3,3,2,2,2,2}};

                double k = 0;

                int i = 0, j = 0;

                for (i = 0; (Ktab[i][0]) <= ms; i++)
                {
                    for (j = 0; (Ktab[0][j]) <= mmp; j++)
                    {

                    }
                }
                k = (Ktab[i][j]);
                return k;
            }
            /// <summary>
            /// indice di valutazione del livello di pressione sonora di calpestio normalizzato rispetto al tempo di riverberazione
            /// </summary>
            /// <param name="L1nw">indice di valutazione del livello di pressione sonora di calpestio normalizzato,</param>
            /// <param name="V">Volume del vano ricevente in [m³]</param>
            /// <returns>L'nT,w</returns>
            public static double L1nTw(double L1nw, double V)
            {
                double L1nTw = 0;

                L1nTw = L1nw - 10 * Math.Log10(V / 30);

                return L1nTw;
            }



        }
        /// <summary>
        /// Calcola l'indice di faciata
        /// </summary>
        public static class D2mnTw
        {
            public static double D2m_nTw(double R1w, double delta_L, double V, double Stot)
            {
                double D2mntw = 0;
                double To = 0.5;
                D2mntw = R1w + delta_L + 10 * Math.Log10((V) / (6 * To * Stot));
                return D2mntw;
            }
            /// <summary>
            /// Calcola R1w per la facciata
            /// </summary>
            /// <param name="n_sup">numero delle superfici considerate (Pareti+finestre+porte)</param>
            /// <param name="Si">Vettore Superfici degli elementi considerati</param>
            /// <param name="Ri">Rw delle pareti+finestre+porte</param>
            /// <param name="n_pelemt">Numero dei picoli elementi (prese 'daria, cassonetti teparelle</param>
            /// <param name="Dnei">Isolamento oferto dai picoli elementi presenti</param>
            /// <returns>R1w facciata</returns>
            public static double R1w(int n_sup, double[] Si, double[] Ri, int n_pelemt, double[] Dnei)
            {
                int i;
                double R1w = 0;
                double Stot = 0, Ao = 10, K = 2;

                for (i = 0; i < n_sup; i++)
                {

                    Stot += Si[i];

                }
                double Relement = 0;

                for (i = 0; i < n_sup; i++)
                {
                    Relement += (Si[i] / Stot) * Math.Pow(10, (-Ri[i] / 10));
                }

                double Rpicelemet = 0;
                for (i = 0; i < n_pelemt; i++)
                {

                    Rpicelemet += (Ao / Stot) * Math.Pow(10, (-Dnei[i] / 10));

                }

                R1w = -10 * Math.Log10(Relement + Rpicelemet) - K;


                return R1w;
            }
            /// <summary>
            /// Calcola r1w di Facciata
            /// </summary>
            /// <param name="Si">Vettore Superfici degli elementi considerati</param>
            /// <param name="Ri">Rw delle pareti+finestre+porte</param>
            /// <param name="Dnei">Isolamento oferto dai picoli elementi presenti</param>
            /// <param name="K">Contributo per tipologia di giunzione</param>
            /// <returns>R1w facciata</returns>
            public static double R1w(double[] Si, double[] Ri, double[] Dnei, double K)
            {
                int i, n_sup = 0, n_pelement = 0;
                double R1w = 0;
                double Stot = 0, Ao = 10;
                n_sup = Si.GetLength(0);
                n_pelement = Dnei.GetLength(0);


                for (i = 0; i < n_sup; i++)
                {

                    Stot += Si[i];

                }
                double Relement = 0;

                for (i = 0; i < n_sup; i++)
                {
                    Relement += (Si[i] / Stot) * Math.Pow(10, (-Ri[i] / 10));
                }

                double Rpicelemet = 0;
                for (i = 0; i < n_pelement; i++)
                {

                    Rpicelemet += (Ao / Stot) * Math.Pow(10, (-Dnei[i] / 10));

                }

                R1w = -10 * Math.Log10(Relement + Rpicelemet) - K;


                return R1w;
            }
            /// <summary>
            /// Calcola il Delta Lfs dovuto alla forma della faciata
            /// </summary>
            /// <param name="tipo">tipo di faciata varia da 1 a 10</param>
            /// <param name="alfa">coeficiente di assorbimento può essere 0.3 , 0.6 o 0.9</param>
            /// <param name="h">altezza calcolata di veduta</param>
            /// <returns>restituisce il DLfs</returns>
            public static double DeltaLfs(int tipo, double alfa, double h)
            {
                double DLfs = 0;

                switch (tipo)
                {
                    case (1):
                        DLfs = 0;
                        break;
                    case (2):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 0;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 0;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 0;
                            }
                        }
                        break;
                    case (3):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = -1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 1;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 1;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 2;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        break;
                    case (4):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 3;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 3;
                            }
                        }
                        break;
                    case (5):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 3;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 4;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 6;
                            }
                        }
                        break;
                    case (6):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = -1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 1;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = -1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 3;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 3;
                            }
                        }
                        break;
                    case (7):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 0;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 0;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 2;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 3;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 4;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 4;
                            }
                        }
                        break;
                    case (8):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 1;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 1;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 1;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 2;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 2;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 2;
                            }
                        }
                        break;
                    case (9):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 2;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 3;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 4;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 4;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 4;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 1;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 5;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 5;
                            }
                        }
                        break;
                    case (10):
                        if (alfa <= 0.3)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 3;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 5;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 6;
                            }
                        }
                        if (alfa == 0.6)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 3;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 6;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 6;
                            }
                        }
                        if (alfa >= 0.9)
                        {
                            if (h < 1.5)
                            {
                                DLfs = 3;
                            }
                            if (h >= 1.5 && h <= 2.5)
                            {
                                DLfs = 7;
                            }
                            if (h > 2.5)
                            {
                                DLfs = 7;
                            }
                        }
                        break;
                }
                return DLfs;
            }

        }

        /// <summary>
        /// calcola la massa frontale o superficiale del componente -("da non confondere con Ms")
        /// </summary>
        /// <param name="str">Oggetto list Layer - lista degli strati che compongono l'elemento costruttivo</param>
        /// <returns>massa frontale [kg/m²]</returns>
        public static double Frontal_Mass(Stratigraphy str)
        {
            double mf = 0;
            foreach (Materiale m in str.Layers)
                mf += m.Tickness * m.Density;

            return mf;

        }
    }
}
